package concurrent.c_006_Lock;

import util.ThreadUtil;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadLocalRandom;

/**
 * https://blog.csdn.net/f641385712/article/details/85014986
 * CountDownLatch 这个类使一个线程等待其他线程各自执行完毕后再执行。
 * 通过一个计数器来实现的，计数器的初始值是线程的数量。
 * 每当一个线程执行完毕后，计数器的值就 -1，当计数器的值为 0 时，表示所有线程都执行完毕，然后在闭锁上等待的线程就可以恢复工作了
 * <p>
 * await() // 调用 await() 方法的线程会被挂起，它会等待直到 count 值为 0 才继续执行
 * boolean await(long timeout, TimeUnit unit) // 和 await() 类似，只不过等待一定的时间后 count 值还没变为 0 的话就会继续执行
 * void countDown() // 将 count 值减 1
 */
public class T06_CountDownLatch {
    public static void main(String[] args) throws InterruptedException {
        usingJoin();
        usingCountDownLatch();
    }

    private static void usingCountDownLatch() throws InterruptedException {
        Thread[] threads = new Thread[5];
        CountDownLatch latch = new CountDownLatch(threads.length);
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(() -> {
                ThreadUtil.sleepSeconds(ThreadLocalRandom.current().nextInt(1, 3));
                latch.countDown(); // 当前线程执行完 -1
            });
            threads[i].start();
        }

        // 其它线程全部执行完
        latch.await();
        System.out.println("end latch");
    }

    private static void usingJoin() throws InterruptedException {
        Thread[] threads = new Thread[5];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(() -> ThreadUtil.sleepSeconds(ThreadLocalRandom.current().nextInt(1, 3)));
            threads[i].start();
            // 让 thread 线程执行完后 main 线程再执行
            threads[i].join();
        }
        System.out.println("end join");
    }
}